<?php
/**
 * @version		$Id: example.php 10381 2008-06-01 03:35:53Z pasamio $
 * @package		Joomla
 * @subpackage	JFramework
 * @copyright	Copyright (C) 2005 - 2008 Open Source Matters. All rights reserved.
 * @license		GNU/GPL, see LICENSE.php
 * Joomla! is free software. This version may have been modified pursuant
 * to the GNU General Public License, and as distributed it includes or
 * is derivative of works licensed under the GNU General Public License or
 * other free or open source software licenses.
 * See COPYRIGHT.php for copyright notices and details.
 */

// Check to ensure this file is included in Joomla!
defined( '_JEXEC' ) or die( 'Restricted access' );

jimport( 'joomla.plugin.plugin' );

/**
 * Example Authentication Plugin
 *
 * @package		Joomla
 * @subpackage	JFramework
 * @since 1.5
 */
class plgAuthenticationOtp extends JPlugin
{
	/**
	 * Constructor
	 *
	 * For php4 compatability we must not use the __constructor as a constructor for plugins
	 * because func_get_args ( void ) returns a copy of all passed arguments NOT references.
	 * This causes problems with cross-referencing necessary for the observer design pattern.
	 *
	 * @param	object	$subject	The object to observe
	 * @param	array	$config		An array that holds the plugin configuration
	 * @since	1.5
	 */
	function plgAuthenticationOtp(& $subject, $config)
	{
		parent::__construct($subject, $config);
	}

	/**
	 * This method should handle any authentication and report back to the subject
	 *
	 * @access	public
	 * @param	array	$credentials	Array holding the user credentials
	 * @param	array	$options		Array of extra options
	 * @param	object	$response		Authentication response object
	 * @return	boolean
	 * @since	1.5
	 */
	function onAuthenticate( $credentials, $options, &$response )
	{
		jimport('joomla.user.helper');
		
		if (empty($credentials['password']))
		{
			$response->status = JAUTHENTICATE_STATUS_FAILURE;
			$response->error_message = 'Empty password not allowed';
			return false;
		}
		
		// Get a database object
		$db =& JFactory::getDBO();
		$hasOTP = false;
		
		if(JPluginHelper::isEnabled('authentication', 'otp'))
		{
			$query = "SELECT id from #__otpusers WHERE username=" . $db->Quote($credentials['username']);
			$db->setQuery($query);
			$result = $db->loadObject();
			if($result)
				$hastOTP = true;
		}
		
		
		if($hasOTP = true AND JPluginHelper::isEnabled('authentication', 'otp'))
			$query = "SELECT u.id, u.password, u.gid, o.otp FROM  #__users as u INNER JOIN #__otphashes as o WHERE o.username = u.username AND u.username=" . $db->Quote($credentials['username']);
		else
			$query = 'SELECT `id`, `password`, `gid`' . ' FROM `#__users`'. ' WHERE username=' . $db->Quote($credentials['username']);
		$db->setQuery( $query );
		$result = $db->loadObject();


		if($result)
		{
			if($hasOTP == true AND JPluginHelper::isEnabled('authentication', 'otp') AND $credentials['otp'] != NULL)
			{
				if($result->otp == $credentials['otp'])
				{
					$parts	= explode( ':', $result->password );
					$crypt	= $parts[0];
					$salt	= @$parts[1];
					$testcrypt = JUserHelper::getCryptedPassword($credentials['password'], $salt);

					if ($crypt == $testcrypt) {
						$user = JUser::getInstance($result->id); // Bring this in line with the rest of the system
						$response->email = $user->email;
						$response->fullname = $user->name;
						$response->status = JAUTHENTICATE_STATUS_SUCCESS;
						$response->error_message = '';
					} else {
						$response->status = JAUTHENTICATE_STATUS_FAILURE;
						$response->error_message = 'Invalid password';
					}
				}else
				{
					$response->status = JAUTHENTICATE_STATUS_FAILURE;
					$response->error_message = 'Invalid password';
				}
			}
			else
			{
				$parts	= explode( ':', $result->password );
				$crypt	= $parts[0];
				$salt	= @$parts[1];
				$testcrypt = JUserHelper::getCryptedPassword($credentials['password'], $salt);

				if ($crypt == $testcrypt) {
					$user = JUser::getInstance($result->id); // Bring this in line with the rest of the system
					$response->email = $user->email;
					$response->fullname = $user->name;
					$response->status = JAUTHENTICATE_STATUS_SUCCESS;
					$response->error_message = '';
				} else {
					$response->status = JAUTHENTICATE_STATUS_FAILURE;
					$response->error_message = 'Invalid password';
				}
			}
		}
		else
		{
			$response->status = JAUTHENTICATE_STATUS_FAILURE;
			$response->error_message = 'User does not exist';
		}
		
	}

	function getOTP64($otp)
	{
		$lookupChar = "123456789abcdefhkmnprstuvwxyzABCDEFGHKMNPQRSTUVWXYZ=+[]&@#*{}.%:";

		for($i = 0; $i < 6; $i++)
			$val[$i] = hexdec(substr($otp, $i * 2, 2));

		$tmp1 = $val[0] >> 2;
		$OTP = $lookupChar[$tmp1 & 63];
		$tmp2 = $val[0] - ($tmp1 << 2);
		$tmp1 = $val[1] >> 4;
		$OTP .= $lookupChar[($tmp1 + $tmp2) & 63];
		$tmp2 = $val[1] - ($tmp1 << 4);
		$tmp1 = $val[2] >> 6;
		$OTP .= $lookupChar[($tmp1 + $tmp2) & 63];
		$tmp2 = $val[2] - ($tmp1 << 6);
		$OTP .= $lookupChar[$tmp2 & 63];
		$tmp1 = $val[3] >> 2;
		$OTP .= $lookupChar[$tmp1 & 63];
		$tmp2 = $val[3] - ($tmp1 << 2);
		$tmp1 = $val[4] >> 4;
		$OTP .= $lookupChar[($tmp1 + $tmp2) & 63];
		$tmp2 = $val[4] - ($tmp1 << 4);
		$tmp1 = $val[5] >> 6;
		$OTP .= $lookupChar[($tmp1 + $tmp2) & 63];
		$tmp2 = $val[5] - ($tmp1 << 6);
		$OTP .= $lookupChar[$tmp2 & 63];

		return $OTP;
	}

	function getOTP32($otp)
	{
		$lookupChar = "0123456789abcdefghkmnoprstuvwxyz";

		for($i = 0; $i < 7; $i++)
			$val[$i] = hexdec(substr($otp, $i * 2, 2));

		$tmp1 = $val[0] >> 3;
		$OTP = $lookupChar[$tmp1 & 31];
		$tmp2 = $val[0] - ($tmp1 << 3);
		$tmp1 = $val[1] >> 6;
		$OTP .= $lookupChar[($tmp1 + $tmp2) & 31];
		$tmp2 = ($val[1] - ($tmp1 << 6)) >> 1;
		$OTP .= $lookupChar[$tmp2 & 31];
		$tmp2 = $val[1] - (($val[1] >> 1) << 1);
		$tmp1 = $val[2] >> 4;
		$OTP .= $lookupChar[($tmp1 + $tmp2) & 31];
		$tmp2 = $val[2] - ($tmp1 << 4);
		$tmp1 = $val[3] >> 7;
		$OTP .= $lookupChar[($tmp1 + $tmp2) & 31];
		$tmp2 = ($val[3] - ($tmp1 << 7)) >> 2;
		$OTP .= $lookupChar[$tmp2 & 31];
		$tmp2 = $val[3] - (($val[3] - ($tmp1 << 7)) >> 2) << 2;
		$tmp1 = $val[4] >> 5;
		$OTP .= $lookupChar[($tmp1 + $tmp2) & 31];
		$tmp2 = $val[4] - ($tmp1 << 5);
		$OTP .= $lookupChar[$tmp2 & 31];
		$tmp1 = $val[5] >> 3;
		$OTP .= $lookupChar[$tmp1 & 31];
		$tmp2 = $val[5] - ($tmp1 << 3);
		$tmp1 = $val[6] >> 6;
		$OTP .= $lookupChar[($tmp1 + $tmp2) & 31];

		return $OTP;
	}


	/*
	function checkOTP($username, $password,$db)
	{
		
		
		$result = mysql_query($query);
		if(mysql_num_rows($result) > 0)
		{
			$otp = mysql_fetch_assoc($result);
			$otphash = $otp['otphash'];
			$maxperiod = 3; // in minutes +/- 3 minutes
			$time = round(gmdate("U") / 60);

			$query = "DELETE FROM jos_otphashes WHERE UNIX_TIMESTAMP('whencreated') <= UNIX_TIMESTAMP(NOW()) - 600";
			mysql_query($query);

			$query = "SELECT * FROM jos_otphashes WHERE username='" . $username . "' AND otp ='" . $password ."'";

			if(mysql_num_rows(mysql_query($query)) <= 0)
			{
				$query = "INSERT INTO jos_otphashes  SET  whencreated=NOW(),username='" . $username . "',otp='" . $password ."'";
				mysql_query($query);
				for($i = $time - $maxperiod; $i <= $time + $maxperiod; $i++)
				{
					if(strlen($password) == 8)
						$md5 = getOTP64(md5("$i$otphash"));
					else
						$md5 = getOTP32(md5("$i$otphash"));

					if($password == $md5)
						return(true);
				}
			}
		}
		return(false);
	}
	*/

}

